﻿using System;
using System.IO;
using System.Runtime.Serialization;
using Jason.ComponentModel;
using Jason.Configuration;
using Jason.Factories;
using Jason.Handlers;
using Jason.Runtime;
using Jason.Server.WcfServices;
using StructureMap;
using Topics.Radical.Reflection;

namespace Command.Host.Infrastructure
{
    public class ServerBootstrapper
    {
        private readonly string _directory;

        public ServerBootstrapper(String directory)
        {
            _directory = directory;
        }

        public IServiceProvider Boot()
        {
            var container = new Container(c =>
            {
                c.For<ICommandHandlersProvider>().Use<DefaultCommandHandlersProvider>();
                c.For<IJobHandlersProvider>().Use<DefaultJobHandlersProvider>();
                c.For<IJobTaskHandlersProvider>().Use<DefaultJobTaskHandlersProvider>();
                c.For<IWorkerService>().Use<WorkerService>();
                c.For<IInterceptorProvider>().Use<DefaultInterceptorProvider>();
                c.For<ICommandInterceptor>().Use<EmptyCommandInterceptor>();
            });

            var adapter = new StructureMapServiceProvider(container);
            container.Configure(c => c.For<IServiceProvider>().Use(adapter));

            var configurator = new DefaultJasonServerConfiguration(_directory)
            {
                AssemblySelector = s => s.Contains("Command.Core"),
                RegisterAsTransient = (contracts, implementation) => container.Configure(c =>
                {
                    foreach (var contract in contracts)
                        c.For(contract).Use(implementation);
                }),
                CommandsSelector = ExecuteCommandsSelector
            };
            configurator.Initialize();

            return adapter;
        }

        private static Boolean ExecuteCommandsSelector(Type t)
        {
            //var isCommand = t.IsAttributeDefined<DataContractAttribute>() && t.Name.EndsWith("Handler");
            var isCommand = t.Name.EndsWith("Handler");
            return isCommand;
        }
    }
}